﻿#include <iostream>
#include <assert.h>
#include <malloc.h>

using namespace std;

//友元
//class Time
//{
//	//友元类
//	friend class Date;
//public:
//	Time(int hour = 0, int minute = 0, int second = 0)
//		:_hour(hour)
//		,_minute(minute)
//		,_second(second)
//	{}
//private:
//	int _hour;
//	int _minute;
//	int _second;
//};
//
//class Date
//{
//	//友元函数
//	friend ostream& operator<<(ostream& out, const Date& d);
//public:
//	
//	//要访问Time类内的成员，使用友元类
//	void SetDateTime(int hour,int minute,int second)
//	{
//		_t._hour = hour;
//		_t._minute = minute;
//		_t._second = second;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//
//	Time _t;
//};
//ostream& operator<<(ostream& out, const Date& d)
//{
//	out << d._year << "-" << d._month << "-" << d._day << endl;
//	return out;
//}
//int main()
//{
//	Date d1;
//	d1.SetDateTime(1, 1, 1);
//
//	return 0;
//}

//class Date
//{
//public:
//
//	//成员变量 写的位置不唯一 但尽量写在一起
//private:
//	int _year;
//	int _month;
//	int _day;
//};


//内部类：在一个类里面再定义一个类
//class A
//{
//private:
//	static int k;
//	int h;
//public:
//	//内部类
//	class B//B天生是A的有友元
//	{
//	public:
//		void foo(const A& a)
//		{
//			cout << k << endl;
//			cout << a.h << endl;
//		}
//	private:
//		int _b;
//	};
//	void Print(const B&b)
//	{
//		b._b;//访问不到
//	}
//};
//int main()
//{
//	A aa;//只有A的成员 
//	cout << sizeof(A) << endl;
//	return 0;
//}


//class Weight
//{
//public:
//	Weight()
//	{
//		cout << "Weight()" << endl;
//	}
//
//	Weight(const Weight& w)
//	{
//		cout << "Weight const Weight& w" << endl;
//	}
//
//	Weight& operator=(const Weight& w)
//	{
//		cout << "Weight& operator=(const Weight& w)" << endl;
//		return *this;
//	}
//	~Weight()
//	{
//		cout << "~Weight()" << endl;
//	}
//};
//
//Weight f(Weight u)
//{
//	Weight v(u);
//	Weight w = v;
//
//	return w;
//}
//
//int main()
//{
//	Weight x;
//	Weight y = f(f(f(x)));//几次拷贝构造？
//}
////《深度探索C++对象模型》
//int main()
//{
//	//Weight x;
//	//f(x);  //4次拷贝构造
//
//	//Weight();//匿名对象，声明周期只在这一行
//	////构造调完之后立马会调用析构函数
//	//f(x);
//
//	//f(Weight());//三次？ 因为编译器优化了
//	//出现连续的构造+拷贝构造,编译器会对其进行优化--直接构造一次
//
//	Weight x;
//	//Weight ret = f(x);//4次拷贝构造
//	//本应该是5次但是连续步骤的构造+拷贝构造,
//	//或者拷贝构造+拷贝构造,编译器可能就会优化,合二为一
//	//这样写更优
//	Weight ret;
//	ret = f(x);//4次拷贝构造+1次赋值
//
//	return 0;
//}




//-------------------------------------------------------
// C/C++ 内存管理

//malloc是开空间 calloc是开空间+初始化
//calloc = malloc+memset
//relloc分原地扩和易地扩

//new的用法

//对于内置类型而言，用malloc和new除了用法不同，没有什么区别
//他们的区别在于自定义类型:malloc只开空间，new不仅开空间还调用构造函数初始化
//int main()
//{
//	int* p1 = new int;//new一个int对象
//	int* p2 = new int[10];//new10个对象
//
//	int* p3 = new int(10);//new一个int对象，初始化成10
//	
//	//new10个int对象，第一个对象是10，剩下是0
//	int* p4 = new int[10]{ 10 };
//	
//
//	//delete一定要匹配 不匹配可能会报错
//	delete p1;
//	delete[] p2;
//	delete p3;
//	delete[] p4;
//	return 0;
//}

//C语言
//struct ListNode
//{
//	ListNode* _next;
//	ListNode* _prev;
//	int _val;
//	ListNode(int val = 0)
//		:_next(nullptr)
//		, _prev(nullptr)
//		, _val(val)
//	{
//
//	}
//};
//struct ListNode* BuyListNode(int x)
//{
//	struct ListNode* node = (struct ListNode*)malloc(sizeof(struct ListNode));
//	assert(node);
//	node->_next = NULL;
//	node->_val = x;
//	return node;
//}
//
//class List
//{
//public:
//	List()
//	{
//		_head = new ListNode;//不仅开空间  还会初始化
//		_head->_next = _head;
//		_head->_prev = _head;
//
//	}
//	ListNode* Find(int x);
//
//private:
//	ListNode* _head;
//
//};
////C++
//int main()
//{
//	ListNode* n1 = (struct ListNode*)malloc(sizeof(struct ListNode));
//	ListNode* n2 = new ListNode(2);
//	ListNode* n3 = new ListNode(3);
//	ListNode* n4 = new ListNode(4);
//	 
//	return 0;
//}


//class Stack
//{
//public:
//	Stack(int capacity = 10)
//	{
//		_a = new int[capacity];
//		_capacity = capacity;
//		_top = 0;
//	}
//	
//	~Stack()
//	{
//		delete[] _a;
//		_capacity = 0;
//		_top = 0;
//	}
//
//private:
//	int* _a;
//	int _capacity;
//	int _top;
//}; 

//int main()
//{
//	//Stack st;
//
//	//malloc失败，返回空指针
//	Stack* ps1 = (Stack*)malloc(sizeof(Stack));
//	assert(ps1);
//
//	//new失败，抛异常
//	Stack* ps2 = new Stack;//开空间+调用构造函数
//
//	free(ps1);
//	delete ps2;//调用析构函数清理资源 + 释放空间
//
//	return 0;
//}

//operator new : 封装了malloc,malloc失败抛异常
//operator delete : 封装了free

//int main()
//{
//	Stack* ps1 = (Stack*)operator new(sizeof(Stack));
//	operator delete(ps1);
//
//	Stack* ps2 = (Stack*)malloc(sizeof(Stack));
//	assert(ps2);
//	free(ps2);
//
//	Stack* ps3 = new Stack;
//	//1.call malloc 如果失败返回nullptr,但是面向对象一般都是抛出异常 因此更喜欢使用
//	//  call operator new 如果失败会抛出异常
//	//2.call Stack  构造函数
//	return 0;
//}


//int main()
//{
//	Stack* stArray = new Stack[10];//调用operator new[]
//
//
//	//假如空间开好了 能不能初始化
//	Stack* obj = (Stack*)operator new(sizeof(Stack));
//	//可以 使用定位new
//	new(obj)Stack(4);//显示调用构造函数 初始化成4
//
//	return 0;
//}


//int globalVar = 1;
//static int staticGlobalVar = 1;
//void Test()
//{
//	static int staticVar = 1;
//	int localVar = 1;
//	int num1[10] = { 1, 2, 3, 4 };
//	char char2[] = "abcd";
//	const char* pChar3 = "abcd";
//	int* ptr1 = (int*)malloc(sizeof(int) * 4);
//	int* ptr2 = (int*)calloc(4, sizeof(int));
//	int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);
//	free(ptr1);
//	free(ptr3);
//}


//int main()
//{
//	// 动态申请一个int类型的空间
//	int* ptr1 = new int;
//
//	// 动态申请一个int类型的空间并初始化为10
//	int* ptr2 = new int(10);
//
//	// 动态申请3个int类型的空间(数组)
//	int* ptr3 = new int[3];
//
//	// 动态申请3个int类型的空间,初始化第一个空间值为1
//	int* ptr4 = new int[3]{ 1 };
//
//	delete ptr1;
//	delete ptr2;
//	delete[] ptr3;
//	delete[] ptr4;
//
//	return 0;
//}


//int main()
//{
//	int* ptr1 = new int;
//
//	int* ptr2 = new int(10);
//
//	int* ptr3 = new int[3];
//
//	int* ptr4 = new int[3]{ 1 };
//
//	delete ptr1;
//	delete ptr2;
//	delete[] ptr3;
//	delete[] ptr4;
//
//	return 0;
//}

//对于自定义类型
//class A {
//public:
//	A(int a = 0)
//		: _a(a)
//	{
//		cout << "A():" << this << endl;
//	}
//	~A()
//	{
//		cout << "~A():" << this << endl;
//	}
//private:
//	int _a;
//};
//int main()
//{
//	// new/delete 和 malloc/free最大区别是 new/delete对于【自定义类型】除了开空间
//	//还会调用构造函数和析构函数
//	A* p1 = (A*)malloc(sizeof(A));
//	A* p2 = new A(1);
//	free(p1);
//	delete p2;
//
//	return 0;
//}

//int main()
//{
//	void* p0 = malloc(1024 * 1024 * 1024);
//	cout << p0 << endl << endl;
//
//	//malloc失败，返回空指针
//	void* p1 = malloc(1024 * 1024 * 1024);
//	cout << p1 << endl << endl;
//
//	try
//	{
//		//new失败，抛异常
//		void* p2 = new char[1024 * 1024 * 1024];
//		cout << p2 << endl;
//	}
//	catch (const exception& e)
//	{
//		cout << e.what() << endl << endl;
//	}
//
//	return 0;
//}


//operator new 源码
//void* __CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc) {
//	// try to allocate size bytes
//	void* p;
//	while ((p = malloc(size)) == 0)
//		if (_callnewh(size) == 0)
//		{
//			// report no memory
//			// 如果申请内存失败了，这里会抛出bad_alloc 类型异常
//			static const std::bad_alloc nomem;
//			_RAISE(nomem);
//		}
//	return (p);
//}

////operator delete 源码
//void operator delete(void* pUserData) {
//	_CrtMemBlockHeader* pHead;
//	RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));
//	if (pUserData == NULL)
//		return;
//	_mlock(_HEAP_LOCK);  /* block other threads */
//	__TRY
//		        /* get a pointer to memory block header */
//		pHead = pHdr(pUserData);
//	         /* verify block type */
//	_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
//	_free_dbg(pUserData, pHead->nBlockUse);
//	__FINALLY
//		_munlock(_HEAP_LOCK);  /* release other threads */
//	__END_TRY_FINALLY
//		return;
//}



//class A {
//public:
//	A(int a = 0)
//		: _a(a)
//	{
//		cout << "A():" << this << endl;
//	}
//	~A()
//	{
//		cout << "~A():" << this << endl;
//	}
//private:
//	int _a;
//};
//int main()
//{
//	//跟malloc功能一样，失败以后抛出异常
//	A* ps1 = (A*)operator new(sizeof(A));
//	operator delete(ps1);
//
//	A* ps2 = (A*)malloc(sizeof(A));
//	free(ps2);
//
//	A* ps3 = new A; //operator new + A的构造函数
//	delete ps3;
//
//	return 0;
//}


//class A {
//public:
//	A(int a = 0)
//		: _a(a)
//	{
//		cout << "A():" << this << endl;
//	}
//
//	// 专属的operator new
//	void* operator new(size_t n)
//	{
//		void* p = nullptr;
//		p = allocator<A>().allocate(1);
//		cout << "memory pool allocate" << endl;
//		return p;
//	}
//
//	void operator delete(void* p)
//	{
//		allocator<A>().deallocate((A*)p, 1);
//		cout << "memory pool deallocate" << endl;
//
//	}
//
//	~A()
//	{
//		cout << "~A():" << this << endl;
//	}
//private:
//	int _a;
//};
//int main()
//{
//	int n = 0;
//	cin >> n;
//	for (int i = 0; i < n; ++i)
//	{
//		A* ps1 = new A; //operator new + A的构造函数
//	}
//
//	return 0;
//}


class A {
public:
	A(int a = 0)
		: _a(a)
	{
		cout << "A():" << this << endl;
	}
	~A()
	{
		cout << "~A():" << this << endl;
	}
private:
	int _a;
};
int main()
{
	A* ptr1 = new A[3];
	//delete ptr1;//出错 崩溃
	delete[] ptr1;//没问题

	cout << endl;


	char* p = new char[100];
	//delete p;//不建议这样用

	return 0;
}